package de.gwtprime.server;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.VideoFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import de.gwtprime.client.PrimeService;
import de.gwtprime.server.model.User;
import de.gwtprime.server.sql.HibernateEntityMangerSingelton;
import de.gwtprime.server.util.MailSender;
import de.gwtprime.shared.MyVideoEntry;
import de.gwtprime.shared.Stock;
import de.gwtprime.shared.UserDTO;
import de.gwtprime.util.Helper;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class PrimeServiceImpl extends RemoteServiceServlet implements
PrimeService {

	/**
	 * Logger
	 */
	private static Logger logger = Logger.getLogger(PrimeServiceImpl.class);


	public List<Stock> greetServer(String input) throws IllegalArgumentException, Exception {

		return null;

	}

	/**
	 * Escape an html string. Escaping data received from the client helps to
	 * prevent cross-site script vulnerabilities.
	 * 
	 * @param html the html string to escape
	 * @return the escaped string
	 */
	private String escapeHtml(String html) {
		if (html == null) {
			return null;
		}
		return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
				.replaceAll(">", "&gt;");
	}

	@Override
	public UserDTO isLoggedIn() {
		// TODO Auto-generated method stub

		HttpSession session = getThreadLocalRequest().getSession();

		String userName = (String)session.getAttribute("userName");

		if(userName !=null){
			return new UserDTO(userName);
		}
		return null;
	}

	@Override
	public UserDTO login(String userName, String password) {
		if(userName.equals("abc")){

			HttpSession session = getThreadLocalRequest().getSession();
			session.setAttribute("userName", userName);
			return new UserDTO(userName);
		}
		return null;
	}

	@Override
	public void logout() {
		HttpSession session = getThreadLocalRequest().getSession();
		session.invalidate();

	}

	@Override
	public void sendMail(String name, String email, String message) {
		MailSender.sendMailToAdmin("Mail from Stock-Analyzer portal", "Name: "+name+", email: "+email+", Message: "+message);

	}

	@Override
	public List<MyVideoEntry> getVideos(int number) {

		List<MyVideoEntry> list = new ArrayList<MyVideoEntry>();

		try {

			// Create a new YouTube service
			YouTubeService myService = new YouTubeService("My Application");

			// Get a list of all entries
			URL metafeedUrl = new URL("http://gdata.youtube.com/feeds/api/users/HuskyStarcraft/uploads");
			VideoFeed resultFeed = myService.getFeed(metafeedUrl, VideoFeed.class);
			List<VideoEntry> entries = resultFeed.getEntries();

			int maxSize = Math.min(entries.size(), number);
			for(int i=0; i<maxSize; i++) {
				VideoEntry entry = entries.get(i);
				list.add(new MyVideoEntry(entry.getId()));
			}
		}
		catch(AuthenticationException e) {
			e.printStackTrace();
			return null;

		}
		catch(MalformedURLException e) {
			e.printStackTrace();
			return null;
		}
		catch(IOException e) {
			e.printStackTrace();
			return null;
		} catch (com.google.gdata.util.ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		return list;

	}

	@Override
	public void addSubstriber(String eMail) throws Exception {
		

		EntityManagerFactory entityManagerFactory = HibernateEntityMangerSingelton.getEntityManagerFactory();
		EntityManager entityManager = entityManagerFactory.createEntityManager();
		entityManager.getTransaction().begin();
		User user = new User(eMail);
		try {

			entityManager.persist(user);

			entityManager.getTransaction().commit();
			
		}catch (EntityExistsException e){
			throw new Exception("User already exists");

		} catch (Exception e) {
			
			if(e.getCause().getMessage().contains("Duplicate entry")){
				logger.info(String.format("The email adress %s is already subscribed.", eMail));
				throw new Exception(String.format("The email adress %s is already subscribed.", eMail));
			}
			
			logger.error("An error occurred while adding a subscriber to the database", e);
			throw new Exception(e.getMessage());
		}
		
		
		MailSender.sendMail(eMail, "GWT Prime Activation", "Please activate your account by clicking this link:\n "+Helper.getActivationLink(eMail, user.getActivationHash())+"\n\nYour GWT Prime Team");
		logger.info("Subscriber added: "+eMail);

	}


	@Override
	public String testRPCConnection() throws Exception {
		return "Server returns: RPC ok!";
	}

}
